/**
 * 新增修改完成调用 modalFormOk方法 编辑弹框组件ref定义为modalForm
 * 高级查询按钮调用 superQuery方法  高级查询组件ref定义为superQueryModal
 * data中url定义 list为查询列表  delete为删除单条记录  deleteBatch为批量删除
 */
import { filterObj, downloadFile } from '@/utils/util'
import { deleteAction, getAction, postAction } from '@/services/manage'
import { downFile } from '@/services/common'
import Criteria from '@/utils/criteria'
import { OPERATOR } from '@/store/mutation-types'
import { checkPermi, checkRole } from '@/utils/auth'
export default {
  data() {
    return {
      queryParam: {},
      height: 400,
      /* 筛选参数 */
      filters: {},
      sorts: [],
      /* table加载状态 */
      loading: false,
      /* table选中keys*/
      selectedRowKeys: [],
      /* table选中records*/
      selectionRows: [],
      /* 查询折叠 */
      toggleSearchStatus: false,
      /* 高级查询条件生效状态 */
      superQueryFlag: false,
      /* 高级查询条件 */
      superQueryParams: '',
      /** 高级查询拼接方式 */
      superQueryMatchType: 'and',
      labelCol: { span: 5 },
      wrapperCol: { span: 18 },
      listeners: {
        'checkbox-change': this.onSelectChange,
        'checkbox-all': this.onSelectChange
      },
      options: {
        customConfig: { storage: { visible: true, resizable: true }},
        rowConfig: { keyField: 'id' },
        importConfig: {
          remote: true,
          types: ['xls', 'xlsx'],
          importMethod: ({ file, options }) => {
            console.log('=======')
            this.handleImportXls({ file, options })
          }
        },
        exportConfig: {
          remote: true,
          type: 'xlsx' // 导出文件格式
          // exportMethod: ({ options }) => {
          //   this.handleExportXls(options.filename)
          // }
        }
      },
      closeMessage: ''
    }
  },
  computed: {
    gridOptions() {
      return {
        ...this.options,
        ...this.getProxyConfig,
        columns: this.columns,
        toolbarConfig: this.getToolbarConfig,
        sortConfig: this.getSortConfig,
        pagerConfig: this.getPagerConfig,
        height: this.height,
        loading: this.loading
      }
    },
    getPagerConfig() { // 自定义pagerConfig配置。 不需要pagerConfig时，页面设置vxe-grid，:pagerConfig="false"
      const pagerConfig = {
        pageSize: 10,
        pageSizes: [10, 20, 50, 100],
        layouts: ['Sizes', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'FullJump', 'PageCount', 'Total']
      }
      return Object.assign({}, pagerConfig, this.pagerConfig || {})
    },
    getToolbarConfig() { // 不需要tool时，页面设置toolbarConfig="{}"
      const toolbar = this.getToolbarByAuth()
      const exportComp = this.getExportComponent()
      exportComp && toolbar.tools.unshift(exportComp)
      this.fieldList && toolbar.tools.unshift({ toolRender: { name: 'VxeToolbarSearch', props: { fieldList: this.fieldList }, events: { click: this.handleSuperQuery }}})
      const toolbarConfig = {
        refresh: {
          query: () => {
            this.onClearSelected()
            this.loadData('query')
          }
        },
        zoom: true,
        custom: true,
        perfect: true,
        import: this.hasAuthKey('save') ? this.hasAuth('save') : this.hasAuth('add'), // 导入权限按新增处理
        slots: {},
        buttons: toolbar.buttons,
        tools: toolbar.tools,
        'class-name': 'z-vxe-toolbar'
      }
      const defaultConfig = {
        export: false // 强制隐藏vxetable原有导出，使用自定义导出
      }
      return Object.assign({}, toolbarConfig, this.toolbarConfig || {}, defaultConfig)
    },
    getSortConfig() { // 不需要排序时页面设置sortConfig="{}"
      const sortConfig = {
        trigger: 'cell',
        remote: true,
        defaultSort: {
          field: 'createTime',
          order: 'desc'
        }
      }
      return Object.assign({}, sortConfig, this.sortConfig || {})
    },
    getProxyConfig() {
      const proxyConfig = {
        seq: false, // 启用动态序号代理
        sort: true, // 启用排序代理
        autoLoad: true, // 初始化请求数据，不请求设置为false
        props: { // 自定义响应结果读取的字段，例如返回结果为：{result: [], page: {total: 10}}
          result: 'result.content',
          total: 'result.totalElements',
          list: 'result'
        },
        ajax: {
          // 接收 Promise 对象
          query: ({ page, sorts }) => {
            this.ipagination = page
            sorts.length > 0 ? this.sorts = sorts : ''
            return this.loadTableData(page)
          }
        }
      }
      return this.disabledProxy ? {} : { proxyConfig: Object.assign({}, proxyConfig, this.proxyConfig) } // 需要手动发起请求时，disabledProxy设置为true
    }
  },
  methods: {
    loadData(type) { // type类型为 reload、query 参考vxe-table文档setup.toolbar.buttons，code参数
      this.$nextTick(() => {
        this.$refs.vxeTable.commitProxy(type || 'query')
      })
    },
    async loadTableData() {
      if (!this.url.list) {
        this.$message.error('请设置url.list属性!')
        return
      }
      let params = this.getQueryParams()// 查询条件
      this.loading = true
      let res = await getAction(this.url.list, params)
      if (res.success && res.result.last && res.result.content.length === 0) { // 当最后一页无数据时，重新请求
        this.ipagination.currentPage = 1
        params = this.getQueryParams()// 查询条件
        res = await getAction(this.url.list, params)
      }
      this.loading = false
      return res
    },
    getQueryParams() { // 获取查询条件
      const queryParam = new Criteria()
      queryParam.addCriterions(Object.assign({}, filterObj(this.queryParam), this.filters), OPERATOR.LIKE)// 过滤参数转换为jpa支持格式
      if (this.superQueryParams) { // 添加高级查询参数
        queryParam.concatCriterions(this.superQueryParams)
      }
      if (this.sorts.length > 0) {
        this.sorts.forEach(item => {
          queryParam.addOrder({ // 增加排序规则,支持组合排序
            fieldName: item.property,
            desc: item.order === 'desc'
          })
        })
      }
      var param = Object.assign({}, { criteria: queryParam.getEncode() })
      param.pageNo = this.ipagination.currentPage
      param.pageSize = this.ipagination.pageSize
      return filterObj(param)
    },
    onSelectChange({ records }) { // 记录选中状态
      this.selectedRowKeys = []
      records.forEach(item => {
        const rowId = this.$refs.vxeTable.getRowid(item)
        this.selectedRowKeys.push(rowId)
      })
      this.selectionRows = records
    },
    onClearSelected() { // 清空选择行
      this.selectedRowKeys = []
      this.selectionRows = []
    },
    searchQuery() { // 查询
      this.onClearSelected()
      // this.$refs.vxeTable.commitProxy('query')
      this.loadData('query')
    },
    searchReset() { // 重置
      this.onClearSelected()
      this.queryParam = {}
      this.loadData('reload')
    },
    async batchDel() { // 批量删除
      if (!this.url.deleteBatch) {
        this.$message.error('请设置url.deleteBatch属性!')
        return
      }
      if (this.selectedRowKeys.length <= 0) {
        this.$message.warning('请选择一条记录！')
        return
      }
      if (typeof this.batchDelBefore === 'function') {
        // 批量删除之前执行判断，是否能删除,支持异步
        const message = await this.batchDelBefore()
        if (message) {
          return this.$message.warning(message)
        }
      }
      this.$confirm({
        title: '确认删除',
        content: '是否删除选中数据?',
        onOk: () => {
          this.loading = true
          deleteAction(`${this.url.deleteBatch}${this.selectedRowKeys.join()}`).then((res) => {
            if (res.success) {
              this.$message.success(res.message)
              // this.$refs.vxeTable.commitProxy('query')
              this.loadData('query')
              this.onClearSelected()
            }
          }).finally(() => {
            this.loading = false
          })
        }
      })
    },
    async handleDelete(id) { // 单行删除
      if (!this.url.delete) {
        this.$message.error('请设置url.delete属性!')
        return
      }
      if (typeof this.deleteBefore === 'function') {
        // 批量删除之前执行判断，是否能删除,支持异步
        const message = await this.deleteBefore()
        if (message) {
          return this.$message.warning(message)
        }
      }
      deleteAction(`${this.url.delete}${id}`).then((res) => {
        if (res.success) {
          this.$message.success(res.message)
          this.loadData()
        }
      })
    },
    async handleEdit(record) { // 编辑
      if (typeof this.editBefore === 'function') {
        // 编辑之前执行判断，是否能编辑,支持异步
        const message = await this.editBefore()
        if (message) {
          return this.$message.warning(message)
        }
      }
      this.$refs.modalForm.edit({ ...record })
      this.$refs.modalForm.title = '编辑'
      this.$refs.modalForm.disableSubmit = false
    },
    async handleAdd() { // 新增
      if (typeof this.addBefore === 'function') {
        // 新增之前执行判断，是否能新增,支持异步
        const message = await this.addBefore()
        if (message) {
          return this.$message.warning(message)
        }
      }
      this.$refs.modalForm.add()
      this.$refs.modalForm.title = '新增'
      this.$refs.modalForm.disableSubmit = false
    },
    handleToggleSearch() { // 筛选条件显示、隐藏
      this.toggleSearchStatus = !this.toggleSearchStatus
    },
    modalFormOk() { // 新增/修改 成功时，重载列表
      this.loadData('query')
    },
    handleDetail: function(record) { // 查看详情
      this.$refs.modalForm.disableSubmit = true
      this.$refs.modalForm.edit(record)
      this.$refs.modalForm.title = '详情'
    },
    handleSuperQuery(params) {
      // 高级查询方法
      if (!params) {
        this.superQueryParams = ''
      } else {
        this.superQueryParams = params
      }
      this.onClearSelected()
      this.loadData()
    },
    handleExportXls(code, fileName) { // 导出
      if (this.closeMessage) {
        return
      }
      this.closeMessage = this.$message.loading('下载中..', 0)
      const param = this.getQueryParams()
      const { pager } = this.$refs.vxeTable.getProxyInfo()
      param.pageNo = 1
      param.pageSize = pager.total + 999 // 防止出现并发时，下载数据少
      const type = this.options.exportConfig.type || 'xls'
      downFile(`excel/export/download/${type}/${code}`, param, { _allResponse: true }).then((res) => {
        const { data, headers } = res
        this.closeMessage()
        this.closeMessage = ''
        if (!data) {
          this.$message.warning('文件下载失败')
          return
        }
        // downloadFile(data, fileName + '.' + type)
        var fileName_ = decodeURIComponent(headers['content-disposition'].split(';')[1].split('filename=')[1])
        downloadFile(data, fileName_.slice(1, fileName_.length - 1))
      })
    },
    handleImportXls({ file, options }) { // 页面表格导入
      if (this.closeMessage) {
        return
      }
      /**
       * importTemplateCode 为导入管理模块对应导入模板编码
       * url对象内配置了导入接口时，importTemplateCode可不指定
       */
      if (!this.importTemplateCode && !this.url.import) {
        return this.$message.warning('请先设置导入模板编码')
      }
      this.closeMessage = this.$message.loading('上传中..', 0)
      const formData = new FormData()
      formData.append('file', file)
      const importUrl = this.url.import ? this.url.import : `/excel/import/upload/${this.importTemplateCode}`
      postAction(importUrl, formData).then(res => {
        if (res.success) {
          this.loadData()
          this.$message.success(res.message)
        }
      }).finally(() => {
        this.closeMessage()
        this.closeMessage = ''
      })
    },
    setTableHeight() { // 获取页面高度
      if (this.$refs.vxeTable) {
        const clientHeight = document.documentElement.clientHeight
        const tableTop = this.$refs.vxeTable.$el.getBoundingClientRect().top
        this.height = clientHeight - tableTop - 40
      }
    },
    hasAuth(type) { // 根据标识判断是否有权限
      if (!this.auth) {
        return true
      }
      if (this.auth['permi']) {
        return !this.auth['permi'][type] || checkPermi(this.auth['permi'][type])
      }
      return !this.auth['role'][type] || checkRole(this.auth['role'][type])// 根据角色控制尚未实现
    },
    getExportElementId() { // 获取导出标识，后续导出组件根据标识请求导出模板,一个页面可以有多个导出模板
      if (this.elementId) { // 可以直接在组件data内指定
        return this.elementId
      }
      if (!this.auth) {
        return
      }
      if (this.auth['permi'] && this.auth['permi'].export) { // 可以与权限标识放一起
        return this.auth['permi'].export
      }
      if (this.auth['role'] && this.auth['role'].export) {
        return this.auth['role'].export
      }
      return
    },
    getExportComponent() { // 判断是否需要导出组件
      if ((!this.toolbarConfig || this.toolbarConfig.export !== false) && this.hasAuth('export')) {
        const elementId = this.getExportElementId()
        return { toolRender: { name: 'VxeToolbarExport', props: { icon: 'download', shape: 'circle', elementId: elementId }, events: { click: this.handleExportXls }}}
      }
    },
    getToolbarByAuth() { // 获取有权限的toolbar功能
      const buttons = []; const tools = []
      // 因部分页面新增、编辑使用相同接口。权限控制时也需要一起控制
      // 新增、编辑使用同一个标识控制时，使用save标识，分开控制时使用add、edit标识
      const saveKey = this.hasAuthKey('save') ? 'save' : 'add'
      this.hasAuth(saveKey) && buttons.push({ buttonRender: { name: 'VxeToolbarAdd', events: { click: this.handleAdd }}})
      // 因部分页面删除、批量删除使用相同接口。权限控制时也需要一起控制
      // 删除、批量删除使用同一个标识控制时，使用remove标识，分开控制时使用delete、deleteBatch标识
      const removeKey = this.hasAuthKey('remove') ? 'remove' : 'deleteBatch'
      this.hasAuth(removeKey) && buttons.push({ buttonRender: { name: 'VxeToolbarBatchDel', events: { click: this.batchDel }}})
      return {
        buttons,
        tools
      }
    },
    hasAuthKey(key) { // 判断权限标识对象内是否有该标识
      if (!this.auth) {
        return false
      }
      return (this.auth['permi'] && this.auth.permi[key]) || (this.auth['role'] && this.auth.role[key])
    }
    // initAuth() { // 初始化权限标识,格式如下，也可以直接在页面data内定义auth对象
    //   /**
    //     *  auth:{ //格式为
    //     *    permi:{
    //     *       add:'' || [],//新增
    //     *       edit:[] || '',//编辑
    //     *       save:[] || '',//新增、编辑同时控制
    //     *       deleteBatch:'' || [],//批量删除
    //     *       delete:'' || [],//删除
    //     *       remove:[] || '',新增、编辑同时控制
    //     *       import:'' || [],//导入
    //     *       export:'' || [],//导出
    //     *       table:'' || [],//列表
    //     *     },
    //     *    role:{} //参数与permi相同，后台暂时未实现
    //     *  }
    //   */
    //   const name = this.$options.name
    //   this.auth = {
    //     permi: {
    //       table: `${name}:table`, // 表格数据权限
    //       add: `${name}:add`, // 新增权限
    //       edit: `${name}:edit`, // 编辑权限
    //       delete: `${name}:delete`, // 删除权限
    //       deleteBatch: `${name}:deleteBatch`, // 批量权限
    //       import: `${name}:import`, // 导入权限
    //       export: `${name}:export`// 导出权限
    //     }
    //   }
    // }
  },
  created() {
    this.initAuth && this.initAuth()
  },
  mounted() {
    this.$nextTick(() => {
      this.setTableHeight()
    })
  }
}
